/**
 * 示例：
 * 
 * console.log(AudioRecord.Supported);................查看所有支持的格式
 * 
 * setTimeout(() => {
 *    AudioRecord.Instance.startRecording('audio/webm;codecs=opus',192000);......开始录音
 * }, 5000);
 *
 * setTimeout(async () => {
 *    const blob=await AudioRecord.Instance.stopRecording();............结束录音并获取blob
 *}, 10000);
 *
 */

let instance;
export default class AudioRecorder {
    constructor() {
        this.audioOptions = {};
        this.mediaRecorder = null;
        this.recordedChunks = [];

        this.isRecording = false;
        this.data = null;
    }

    /**
     * 单例
     * @returns {AudioRecorder}
     */
    static get Instance() {
        if (!instance) {
            instance = new AudioRecorder();
        }
        return instance;
    }

    /**
     * 获取所有支持的媒体类型
     * @returns {Array<string>}
     */
    static get Supported() {
        const types = [
            'audio/webm;codecs=opus',
            'audio/ogg;codecs=opus',
            'audio/mpeg',
            'audio/wav',
            'audio/aac',
            'audio/flac',
            'audio/ogg',
            'audio/flac+ogg',
            'audio/alac',
            'audio/wavpack',
            'audio/basic',
            'audio/L16',
            'audio/amr',
            'audio/3gpp',
            'audio/x-ms-wma'
        ];

        const supportedTypes = [];
        types.forEach((type) => {
            if (MediaRecorder.isTypeSupported(type)) {
                supportedTypes.push(type);
            }
        });

        return supportedTypes;
    }

    /**
     * 开始录制
     * @param {string} mimeType 媒体类型
     * @param {number} audioBitsPerSecond 码率
     */
    async startRecording(mimeType, audioBitsPerSecond) {
        let mmt = mimeType;
        let support = false;
        if (MediaRecorder.isTypeSupported(mimeType)) {
            support = true;
        } else {
            support = false;
            mmt = AudioRecorder.Supported[0];
            if (!mmt) {
                console.error('no supported mimeType was found');
            }
            console.warn(`${mimeType} is not supported,now will use default mimeType:${mmt}`);
        }

        this.audioOptions.mimeType = mmt;
        this.audioOptions.audioBitsPerSecond = audioBitsPerSecond || 128000;

        try {
            const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
            this.mediaRecorder = new MediaRecorder(stream, this.audioOptions);

            this.mediaRecorder.ondataavailable = (event) => {
                if (event.data.size > 0) {
                    this.recordedChunks.push(event.data);
                }
            };

            this.mediaRecorder.start();
            this.isRecording = true;
        } catch (error) {
            console.error('Error accessing microphone:', error);
        }
    }

    /**
     * 停止录制，并返回blob（异步）
     * @returns blob
     */
    async stopRecording() {
        if (!this.isRecording) return;
        return new Promise((resolve) => {
            this.mediaRecorder.onstop = () => {
                const blob = new Blob(this.recordedChunks, { type: this.audioOptions.mimeType });
                this.recordedChunks = [];
                resolve(blob);
            };
            this.mediaRecorder.stop();
            this.isRecording = false;
        });
    }
}